//主要是对反射的应用，写完之后加深反射的映像

package main
import (
	"bufio"
	"fmt"
	"io"
	"os"
	"reflect"
	"strconv"
	"strings"
)
type Student struct {
	Name string `ini:"name"`
	Age int `ini:"age"`
}
func main() {
	var stu Student
	mapp,_:=InitoMap("./configure/config.ini")
	Bind(&stu,mapp)
	fmt.Printf("type is :%T , name is %v  ,age is %v \n",stu,stu.Name,stu.Age)
}
//Bind 把map文件解析到结构体中
func Bind(x interface{}, mapp map[string]string) {
	t:=reflect.TypeOf(x).Elem()
	v:=reflect.ValueOf(x).Elem()
	for i:=0;i<t.NumField();i++{
		field:=t.Field(i)
		if targetVal,ok:=mapp[field.Tag.Get("ini")];ok{
			switch v.Field(i).Kind(){
			case reflect.String:
				v.Field(i).SetString(targetVal)
			case reflect.Int:
				val,_:=strconv.Atoi(targetVal)
				v.Field(i).SetInt(int64(val))
			}
		}
	}
}
//InitoMap 读取ini配置到map当中 并返回map
func InitoMap(filePath string)  (map[string]string,error){
	file,err:=os.Open(filePath)
	if err!=nil{
		fmt.Println("open file failed err:",err)
		return nil,err
	}
	defer file.Close()
	resMap:=make(map[string]string)
	reader:=bufio.NewReader(file)
	for {
		line,err:=reader.ReadString('\n')
		if len(line)!=0{
			key,val:=analizeString(line)
			resMap[key]=val
		}
		if err == io.EOF{
			break
		}
	}
	return resMap,nil
}
//analizeString 获得配置文件中每行的内容中的key和value
func analizeString(target string) (key string, val string) {
	index:=strings.Index(target,":")
	key=strings.TrimSpace(target[:index])
	val=strings.TrimSpace(target[index+1:])
	return key ,val
}